home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / mmlc / source / m2ctrl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-29  |  5.3 KB  |  260 lines

  1. /* ------------------------------------------------------------------
  2.                         MML compiler [M2]
  3.                programmed by S.Yamamoto (SHINNOSUKE)
  4.                    m2ctrl.c  --  control line
  5. ------------------------------------------------------------------ */
  6.  
  7. #include    <stdio.h>
  8. #include    <stdlib.h>
  9. #include    <ctype.h>
  10. #include    <string.h>
  11. #include    <limits.h>
  12. #include    "m2.h"
  13.  
  14. #define    SUCCSESS    0
  15. #define    FAILURE    (-1)
  16. #define    TRUE    1
  17. #define    FALSE    0
  18. #define    ERR    (-1)
  19. #define    YES    1
  20. #define    NO    0
  21.  
  22.     /* ROLAND EXCLUSIVE SUM 計算 */
  23. #define    CHECKSUM(x)    (((x)%128!=0)?128-(x)%128:0)
  24.  
  25. static    char    *ctrlCommand[] = {
  26.     "title",
  27.     "copyright",
  28.     "compile",
  29.     "begin",
  30.     "tempo",
  31.     "signature",
  32.     "malloc",
  33.     "division",
  34.     "part",
  35.     "rhmPart",
  36.     "rhmNote",
  37.     "program",
  38.     "memo",
  39.     "\0"
  40. };
  41.  
  42. void    makeHeader(int d)    /* SMFヘッダ */
  43. {
  44.     int    d1;
  45.     int    d2;
  46.  
  47.     d1 = (d & 0xff00) >> 8;
  48.     d2 = d & 0xff;
  49.  
  50.     putData( 14 ,'M' ,'T' ,'h'
  51.         ,'d' ,0 ,0 ,0 ,6 ,0 ,0 ,0 ,1 ,d1 ,d2);
  52.     putData( 8 ,'M' ,'T' ,'r' ,'k' ,0 ,0 ,0 ,0);
  53.     return;
  54. }
  55.  
  56. void    varNum( unsigned long n )    /* 可変長数値表現 */
  57. {
  58.     int    i;
  59.     int    flags = NO;
  60.     int    d[4];    /* 上限4バイト */
  61.  
  62.     for( i=0;i<4;i++ )
  63.         d[i] = (int)(( n >> (i*7)) & 0x7f );
  64.  
  65.     for( i=3;i>=0;i-- ) {
  66.         if( flags == NO && d[i] == 0 && i != 0)
  67.             continue;
  68.         flags = YES;
  69.         putData( 1,(( i==0 ) ? d[i] : d[i] | 0x80));
  70.     }
  71.     return;
  72. }
  73.  
  74. void    putText( char *t )    /* テキスト情報を書き込む */
  75. {
  76.     int    i;
  77.     int    l;
  78.  
  79.     l = strlen(t);
  80.     varNum( l );
  81.     for( i=0;i<l;i++ )
  82.         putData( 1 ,*(t+i) );
  83.     return;
  84. }
  85.  
  86. void    putTempo( int t )    /* テンポを書き込む */
  87. {
  88.     int    tempo1;
  89.     int    tempo2;
  90.     int    tempo3;
  91.     unsigned long    tempo;
  92.  
  93.     tempo = 60000000 / (unsigned long) t;
  94.  
  95.     tempo1 = (int) (( tempo & 0xff0000 ) >> 16 );
  96.     tempo2 = (int) (( tempo & 0xff00 ) >> 8 );
  97.     tempo3 = (int) ( tempo & 0xff );
  98.  
  99.     putData( 6 ,0xff ,0x51 ,0x03 ,tempo1 ,tempo2 ,tempo3 );
  100.     return;
  101. }
  102.  
  103. void    putSignature( int n,int d )    /* 拍子を書き込む */
  104. {
  105.     int    i;
  106.     int    dummy;
  107.     int    denom=ERR;
  108.  
  109.     for( i=0;i<7;i++ ) {
  110.         dummy = power( 2 ,i );
  111.         if( d == dummy ) {
  112.             denom = i;
  113.             break;
  114.         }
  115.     }
  116.  
  117.     if( denom == ERR)    denom = 2;
  118.     putData( 7 ,0xff ,0x58 ,0x04 ,n ,denom ,0x18 ,0x08 );
  119.     return;
  120. }
  121.  
  122. FLGDAT    ctrlLine( void )    /* コントロール行メイン */
  123. {
  124.     char    *param = "param";
  125.     char    *buf;
  126.     char    *rp;
  127.     char    text[3][128];
  128.  
  129.     int    i;
  130.     int    j;
  131.     int    dummy;
  132.     int    n;
  133.     int    endFlags = NO;
  134.  
  135.     int    sigNum = ERR;
  136.     int    sigDen;
  137.  
  138.     FLGDAT    fgset;
  139.  
  140.     strcpy( text[0] ,"no title" );
  141.     strcpy( text[1] ,"no copyright" );
  142.     strcpy( text[2] ,"created by MML compiler [M2] V2.X" );
  143.  
  144.     fgset.tempo = 120;    /* 初期状態 テンポ */
  145.     fgset.wksize = 2048;    /* イベント数 */
  146.     fgset.rpart = -1;
  147.     fgset.div = 48;    /* 分解能 */
  148.     fgset.signature[0] = 4;
  149.     fgset.signature[1] = 4;
  150.  
  151.     for( i=0;i<16;i++ )    fgset.part[i] = i;
  152.     for( i=0;i<=128;i++ )    fgset.program[i] = i;
  153.  
  154.     for( j=0;j<2;j++ )
  155.         for( i=0;i<26;i++ )
  156.             fgset.rnote[i][j] = ERR;
  157.  
  158.     do {
  159.         if(( buf=Pre_fgets() ) == NULL )
  160.             errMsg( MSG_freerr ,"No MML data" );
  161.         rp = skipSpace( buf );
  162.         if( *rp == '\0' )
  163.             continue;
  164.         if( *rp != '.' )
  165.             errMsg( MSG_syntax ,"control" );
  166.         rp = skipSpace( ++rp );
  167.         n = comSearch( ctrlCommand ,rp );
  168.         if( n == ERR )
  169.             errMsg( MSG_undctl ,NULL );
  170.         rp += strlen( ctrlCommand[n] );
  171.         rp = skipSpace( rp );
  172.  
  173.         switch( n ) {
  174.             case 0:
  175.             case 1:
  176.                 strncpy( text[n] ,rp ,127);
  177.                 break;
  178.             case 2:
  179.             case 3:
  180.                 endFlags = YES;
  181.                 break;
  182.             case 4:
  183.                 fgset.tempo = strToInt( &rp,30,600,0,NULL );
  184.                 break;
  185.             case 5:
  186.                 sigNum = strToInt( &rp,1,64,-1,NULL );
  187.                 rp = skipSpace( rp );
  188.                 if( *rp == '/' )    rp++;
  189.                 sigDen = strToInt( &rp,1,64,-1,NULL );
  190.                 break;
  191.             case 6:
  192.                 fgset.wksize = strToInt( &rp,1,INT_MAX,0,NULL );
  193.                 break;
  194.             case 7:
  195.                 fgset.div = strToInt( &rp,48,480,0,NULL );
  196.                 break;
  197.             case 8:
  198.                 rp = skipSpace( rp );
  199.                 dummy = strToInt( &rp,1,16,-1,NULL ) - 1;
  200.                 rp = skipSpace( rp );
  201.                 if( *rp == ',' )    rp++;
  202.                 fgset.part[dummy] = strToInt( &rp,1,16,-1,NULL ) - 1;
  203.                 break;
  204.             case 9:
  205.                 fgset.rpart = strToInt( &rp,1,16,-1,NULL ) - 1;
  206.                 break;
  207.             case 10:
  208.                 dummy = toupper( *rp );
  209.                 if( dummy<'A' || dummy>'Z' || dummy == 'R' )
  210.                     errMsg(MSG_misopd,param);
  211.                 dummy -= 'A';
  212.                 rp++;
  213.                 for( i=0;i<2;i++ ) {
  214.                     rp = skipSpace( rp );
  215.                     if( *rp==',' )    rp++;
  216.                     fgset.rnote[dummy][i] = strToInt( &rp,0,127,-1,NULL );
  217.                 }
  218.                 break;
  219.             case 11:
  220.                 rp = skipSpace( rp );
  221.                 dummy = strToInt( &rp,0,128,-1,NULL );
  222.                 rp = skipSpace( rp ); 
  223.                 if( *rp == ',' )    rp++;
  224.                 fgset.program[dummy] = strToInt( &rp,1,128,-1,NULL );
  225.                 break;
  226.         }
  227.     } while( endFlags == NO );
  228.  
  229.     makeHeader( fgset.div );
  230.  
  231.     for( i=0;i<3;i++ ) {
  232.         putData( 3,0,0xff,i+1 );
  233.         putText( text[i] );
  234.     }
  235.  
  236.     putDisp( "Title         :%s\n",text[0] );
  237.     putDisp( "Copyright     :%s\n",text[1] );
  238.     putDisp( "Division      :%d\n",fgset.div );
  239.     putDisp( "Rhythm MML    :" );
  240.     if( fgset.rpart == -1 )
  241.         putDisp( "OFF\n" );
  242.     else putDisp( "ON (part %d)\n",fgset.rpart + 1 );
  243.  
  244.     putData( 1,0 );
  245.     putTempo( fgset.tempo );
  246.  
  247.     putDisp( "Top tempo     :%d\n",fgset.tempo );
  248.  
  249.     if( sigNum != ERR ) {
  250.         putData( 1,0 );
  251.         putSignature( sigNum,sigDen );
  252.         fgset.signature[0] = sigNum;
  253.         fgset.signature[1] = sigDen;
  254.         putDisp( "Signature     :%d/%d\n",sigNum,sigDen );
  255.     }
  256.  
  257.  
  258.     return( fgset );
  259. }
  260.